#include "omci_me.h"
#include "omci_general_func.h"


/*******************************************************************************************************************************
CTC ONU Loop Detection

********************************************************************************************************************************/
int omciMeInitForOnuLoopDetection(omciManageEntity_t *omciManageEntity_p)
{
	omciManageEntity_ptr tmpOmciManageEntity_p =omciManageEntity_p;

	tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_GET] = omciGetAction;
	tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_SET] = omciSetAction;
	
	return 0;		
}

uint8_t alarmIdLoopDetection[] = {
    OMCI_ALARM_ID_LoopDetection_LoopBack_EthPort1,
	OMCI_ALARM_ID_LoopDetection_LoopBack_EthPort2,
	OMCI_ALARM_ID_LoopDetection_LoopBack_EthPort3,
	OMCI_ALARM_ID_LoopDetection_LoopBack_EthPort4,
	0
};

omciAttriDescript_t omciAttriDescriptListOnuLoopDetection[]={
{0, "meId" ,                            2 ,     ATTR_ACCESS_R,  ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{1, "Operator ID" ,                     4 ,     ATTR_ACCESS_R,  ATTR_FORMAT_STRING,             0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{2, "Loop Detection Management",        2 ,     ATTR_ACCESS_R_W,  ATTR_FORMAT_ENUM,             0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{3, "Looped Port Down",                 2 ,     ATTR_ACCESS_R_W,  ATTR_FORMAT_ENUM,             0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{4, "Loop Dect Msg freq",               2 ,     ATTR_ACCESS_R_W,  ATTR_FORMAT_UNSIGNED_INT,     1,  0xFFFF,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{5, "Loop Recv Interval",				2 , 	ATTR_ACCESS_R_W,  ATTR_FORMAT_UNSIGNED_INT, 	0,	0,	0,		NULL,	 NO_AVC, &generalGetSetFunc},
{6, "Port and VLAN table",				7 , 	ATTR_ACCESS_R_W,  ATTR_FORMAT_TABLE, 	        0,	0,	0,		NULL,	 NO_AVC, &generalGetSetFunc},

{255, "" , 0 , 0,  0, 0,0, 0, NULL , 0, NULL}
};

/*******************************************************************************************************************************
CTC ONU capability

********************************************************************************************************************************/
int omciMeInitForOnuCapability(omciManageEntity_t *omciManageEntity_p)
{
    omciManageEntity_ptr tmpOmciManageEntity_p =omciManageEntity_p;

    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_GET] = omciGetAction;
    
    return 0;       
}

omciAttriDescript_t omciAttriDescriptListOnuCapability[]={
{0, "meId" ,                            2 ,     ATTR_ACCESS_R,  ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{1, "Operator ID" ,                     4 ,     ATTR_ACCESS_R,  ATTR_FORMAT_STRING,             0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{2, "CTC Spec Version",                 1 ,     ATTR_ACCESS_R,  ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{3, "ONU type",                         1 ,     ATTR_ACCESS_R,  ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{4, "ONU Tx power supply control",      1 ,     ATTR_ACCESS_R,  ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetFunc},
{255, "" , 0 , 0,  0, 0,0, 0, NULL , 0, NULL}
};

/*******************************************************************************************************************************
CTC LOID authentication

********************************************************************************************************************************/
int omciMeInitForLoidAuthen(omciManageEntity_t *omciManageEntity_p)
{
    omciManageEntity_ptr tmpOmciManageEntity_p =omciManageEntity_p;

    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_GET] = omciGetAction;
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_SET] = omciSetAction;
    
    return 0;       
}

omciAttriDescript_t omciAttriDescriptListLoidAuthentication[]={
{0, "meId" ,                    2 ,     ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   0,  0,  0,      NULL,   NO_AVC, &generalGetFunc},
{1, "Operator ID" ,             4 ,     ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         0,  0,  0,      NULL,   NO_AVC, &generalGetFunc},
{2, "LOID",                     24 ,    ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         0,  0,  0,      NULL,   NO_AVC, &generalGetFunc},
{3, "Password",                 12 ,    ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         0,  0,  0,      NULL,   NO_AVC, &generalGetFunc},
{4, "Authentication status",    1 ,     ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   0,  0,  0,      NULL,   NO_AVC, &generalGetSetFunc},
{255, "" , 0 , 0,  0, 0,0, 0, NULL , 0, NULL}
};


/*******************************************************************************************************************************
CTC Extended multicast operations profiles

********************************************************************************************************************************/
int omciMeInitForExtendMulticastProfile(omciManageEntity_t *omciManageEntity_p)
{
    omciManageEntity_ptr tmpOmciManageEntity_p =omciManageEntity_p;

    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_GET] = omciGetAction;
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_GET_NEXT] = omciGetNextAction;   
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_SET] = omciSetAction;
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_CREAT] = omciCreateAction;
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_DELETE] = omciDeleteAction;
    tmpOmciManageEntity_p->omciActionFunc[MT_OMCI_MSG_TYPE_SET_TABLE] = omciSetTableAction; 
    
    return 0;       
}



/*******************************************************************************************
**function name
	setEMOPMulticastAclTableValueByType
**description:
	Set ACL Value for OLT request according to the attribute index.
 **retrun :
 	-1:	failure
 	0:	success
**parameter:
  	value :	return value
  	meInstantPtr: 9.3.27 instance pointer
  	omciAttribute: 9.3.27 attribute pointer
  	attrIndex: valid value
  		7: dynamic acl attribute
  		8: static acl attribute
********************************************************************************************/
static int _setEMOPMulticastAclTableValue(uint8_t *value, uint8_t *meInstantPtr , omciAttriDescript_t * omciAttribute, uint8_t flag)
{
	omciTableAttriValue_t *tableConent_ptr = NULL; //table content pointer
	uint8_t *tableValue_ptr = NULL;
	uint8_t *tmp_ptr = NULL;
	omciMeInst_t *tmpomciMeInst_ptr = (omciMeInst_ptr)meInstantPtr;
	uint8_t actionFlag = ATTRIBUTE_TABLE_NULL; 
	uint32_t length = 0;
	int ret = 0;
	uint16_t ctrlField = 0;
	uint8_t setCtrl = 0;      //0:reserved, 1:add or replace entry, 2:del the entry, 3:del all entry
	uint8_t rowPart = 0;
	uint16_t rowID = 0;
	uint8_t rowPart_tmp = 0;
	uint16_t rowID_tmp = 0;
	uint16_t entryLength = 0;
    uint16_t sameEntryNum = 0;
	
	if((tmpomciMeInst_ptr == NULL) || (value == NULL) || (omciAttribute == NULL)){
		return -1;
	}
	entryLength = omciAttribute->attriLen;
	/*parse value*/
	tmp_ptr = (uint8_t *)value;
	ctrlField = get16(tmp_ptr);
	setCtrl = ((ctrlField & OMCI_EMOP_ACL_TABLE_ENTRY_SET_CTRL_MASK) >> OMCI_EMOP_ACL_TABLE_ENTRY_SET_CTRL_FILED);
	rowPart = ((ctrlField & OMCI_EMOP_ACL_TABLE_ENTRY_ROW_PART_MASK) >> OMCI_EMOP_ACL_TABLE_ENTRY_ROW_PART_FILED);
	rowID = (ctrlField & OMCI_EMOP_ACL_TABLE_ENTRY_ROW_ID_MASK);	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s]setCtrl=0x%2x, rowPart=0x%2x, rowID=%d\n",__LINE__, __func__, setCtrl,rowPart,rowID);

	if(setCtrl == 0)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s]unknown setCtrl=0x%2x\n",__LINE__, __func__, setCtrl);
	    return -1;
	}

	if(setCtrl == 3) /*clear all table entry*/
    {
        ret = omciDelTableValueOfInst(tmpomciMeInst_ptr, omciAttribute->attriIndex);
        return ret;
    }
    else
    {
        tableConent_ptr = omciGetTableValueByIndex(tmpomciMeInst_ptr, omciAttribute->attriIndex);
        if(tableConent_ptr != NULL)
            tableValue_ptr = tableConent_ptr->tableValue_p;
            
        tmp_ptr = tableValue_ptr;
        
        /*search current entry*/
        while(tmp_ptr != NULL){
            ctrlField = get16(tmp_ptr);
        	rowPart_tmp = ((ctrlField & OMCI_EMOP_ACL_TABLE_ENTRY_ROW_PART_MASK) >> OMCI_EMOP_ACL_TABLE_ENTRY_ROW_PART_FILED);
        	rowID_tmp = (ctrlField & OMCI_EMOP_ACL_TABLE_ENTRY_ROW_ID_MASK);
            if(rowPart == rowPart_tmp && rowID == rowID_tmp)
            {
                if(setCtrl == 1)
                    actionFlag = ATTRIBUTE_TABLE_REPLACE_ENTRY;
                else if(setCtrl == 2)
                    actionFlag = ATTRIBUTE_TABLE_DEL_ENTRY;
                break;
            }
            length += entryLength;
            if(length >= tableConent_ptr->tableSize){
                if(setCtrl == 1)
                    actionFlag = ATTRIBUTE_TABLE_ADD_ENTRY;
                break;
            }
            tmp_ptr += entryLength;
            sameEntryNum++;
        }

        if(setCtrl == 2 && actionFlag == ATTRIBUTE_TABLE_NULL)
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]can not find del rule\n", __FUNCTION__, __LINE__);
            return -1;
        }
            
        ret = omciAddTableValueToInst(tmpomciMeInst_ptr, tableConent_ptr, omciAttribute, value, sameEntryNum, actionFlag);
    }
    
	return ret;
}

static AttributeFunc _EMOPMulticastDynamicAclTableGetSetFunc = {
	getGeneralTableValue,
	_setEMOPMulticastAclTableValue,
};

static AttributeFunc _EMOPMulticastStaticAclTableGetSetFunc = {
	getGeneralTableValue,
	_setEMOPMulticastAclTableValue,
}; 

static AttributeFunc _EMOPMulticastLostGroupListTableGetSetFunc = {
	getGeneralTableValue,
	NULL,
};

omciAttriDescript_t omciAttriDescriptListExtMulticastProfile[]={
{0, "meId" ,                        2 ,     ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{1, "IGMP Version" ,                1 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{2, "IGMP function",                1 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{3, "Immediate leave",              1 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{4, "Upstream IGMP TCI",            2 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{5, "Upstream IGMP tag control",    1 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{6, "Upstream IGMP rate",           4 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{7, "Dynamic ACL table",            30 ,    ATTR_ACCESS_R_W,                ATTR_FORMAT_TABLE,              0,  0,  0,      NULL,    NO_AVC, &_EMOPMulticastDynamicAclTableGetSetFunc},
{8, "Static ACL table",             30 ,    ATTR_ACCESS_R_W,                ATTR_FORMAT_TABLE,              0,  0,  0,      NULL,    NO_AVC, &_EMOPMulticastStaticAclTableGetSetFunc},
{9, "Lost groups list table",       16 ,    ATTR_ACCESS_R,                  ATTR_FORMAT_TABLE,              0,  0,  0,      NULL,    NO_AVC, &_EMOPMulticastLostGroupListTableGetSetFunc},
{10, "Robustness",                  1 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{11, "Querier IP address",          16 ,    ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,             0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{12, "Querier interval",            4 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{13, "Querier max response time",   4 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{14, "Last member query interval",  4 ,     ATTR_ACCESS_R_W,                ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{15, "Unauthorized join request",   1 ,     ATTR_ACCESS_R_W,                ATTR_FORMAT_UNSIGNED_INT,       0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{16, "Downstream IGMP TCI",         3 ,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_STRING,       		0,  0,  0,      NULL,    NO_AVC, &generalGetSetFunc},
{255, "" , 0 , 0,  0, 0,0, 0, NULL , 0, NULL}
};

